<?php
namespace Terrafirma\Comparator;

use ArrayObject;
use LogicException;

class FixedOrderComparator implements ComparatorInterface
{
	protected $behavior;
	protected $positionMap;
	
	public function __construct(ArrayObject $positionMap, FixedOrderComparatorBehavior $behavior = null)
	{
		$this->behavior = ($behavior ?: FixedOrderComparatorBehavior::ThrowException());
		$this->positionMap = $positionMap;
	}
	
	/**
	 * Compares a left value to a right value and returns an integer comparison
	 * 
	 * @param mixed $left
	 * @param mixed $right
	 * @return int (-1 = less than, 0 = equal, 1 = greater than)
	 */
	public function compare($left, $right)
	{
		$leftPos = $this->getPosition($left);
		$rightPos = $this->getPosition($right);
		
		if(is_null($leftPos) || is_null($rightPos)) {
			switch($this->behavior) {
				case FixedOrderComparatorBehavior::ThrowException:
					throw new LogicException('Cannot compare an unknown input value');
				case FixedOrderComparatorBehavior::Before:
					return (is_null($leftPos) ? (is_null($rightPos) ? 0 : -1) : 1);
				case FixedOrderComparatorBehavior::After:
					return (is_null($leftPos) ? (is_null($rightPos) ? 0 : 1) : -1);
			}
		}
		return ($leftPos > $rightPos ? 1 : ($leftPos < $rightPos ? -1 :0));
	}
	
	public function setPositionMap(ArrayObject $positionMap)
	{
		$this->positionMap = $positionMap;
	}
	
	protected function getPosition($input)
	{
		foreach($this->positionMap as $position => $value) {
			if($input === $value) {
				return $position;
			}
		}
		return null;
	}
}